# Some 2020 player statistics
bref_players_stats(seasons = 2020, tables = c("advanced", "totals"), widen = TRUE, assign_to_environment = TRUE)
## Warning: `tbl_df()` is deprecated as of dplyr 1.0.0.
## Please use `tibble::as_tibble()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
## Warning: `funs()` is deprecated as of dplyr 0.8.0.
## Please use a list of either functions or lambdas:
##
## # Simple named list:
## list(mean = mean, median = median)
##
## # Auto named with `tibble::lst()`:
## tibble::lst(mean, median)
##
## # Using lambdas
## list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
## Warning: Problem with `mutate()` input `Rk`.
## ℹ NAs introduced by coercion
## ℹ Input `Rk` is `Rk %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `Age`.
## ℹ NAs introduced by coercion
## ℹ Input `Age` is `Age %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `G`.
## ℹ NAs introduced by coercion
## ℹ Input `G` is `G %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `MP`.
## ℹ NAs introduced by coercion
## ℹ Input `MP` is `MP %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `PER`.
## ℹ NAs introduced by coercion
## ℹ Input `PER` is `PER %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TS.`.
## ℹ NAs introduced by coercion
## ℹ Input `TS.` is `TS. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3PAr`.
## ℹ NAs introduced by coercion
## ℹ Input `X3PAr` is `X3PAr %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FTr`.
## ℹ NAs introduced by coercion
## ℹ Input `FTr` is `FTr %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `ORB.`.
## ℹ NAs introduced by coercion
## ℹ Input `ORB.` is `ORB. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DRB.`.
## ℹ NAs introduced by coercion
## ℹ Input `DRB.` is `DRB. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TRB.`.
## ℹ NAs introduced by coercion
## ℹ Input `TRB.` is `TRB. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `AST.`.
## ℹ NAs introduced by coercion
## ℹ Input `AST.` is `AST. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `STL.`.
## ℹ NAs introduced by coercion
## ℹ Input `STL.` is `STL. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `BLK.`.
## ℹ NAs introduced by coercion
## ℹ Input `BLK.` is `BLK. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TOV.`.
## ℹ NAs introduced by coercion
## ℹ Input `TOV.` is `TOV. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `USG.`.
## ℹ NAs introduced by coercion
## ℹ Input `USG.` is `USG. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `OWS`.
## ℹ NAs introduced by coercion
## ℹ Input `OWS` is `OWS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DWS`.
## ℹ NAs introduced by coercion
## ℹ Input `DWS` is `DWS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `WS`.
## ℹ NAs introduced by coercion
## ℹ Input `WS` is `WS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `WS.48`.
## ℹ NAs introduced by coercion
## ℹ Input `WS.48` is `WS.48 %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `OBPM`.
## ℹ NAs introduced by coercion
## ℹ Input `OBPM` is `OBPM %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DBPM`.
## ℹ NAs introduced by coercion
## ℹ Input `DBPM` is `DBPM %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `BPM`.
## ℹ NAs introduced by coercion
## ℹ Input `BPM` is `BPM %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `VORP`.
## ℹ NAs introduced by coercion
## ℹ Input `VORP` is `VORP %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## parsed http://www.basketball-reference.com/leagues/NBA_2020_advanced.html
## Warning: All elements of `...` must be named.
## Did you want `dataTable = c(isSeasonCurrent, slugPlayerSeason, slugPlayerBREF, namePlayer,
## slugPosition, agePlayer, slugTeamBREF, countGames, minutes,
## ratioPER, pctTrueShooting, pct3PRate, pctFTRate, pctORB,
## pctDRB, pctTRB, pctAST, pctSTL, pctBLK, pctTOV, pctUSG, ratioOWS,
## ratioDWS, ratioWS, ratioWSPer48, ratioOBPM, ratioDBPM, ratioBPM,
## ratioVORP, isHOFPlayer, slugTeamsBREF, countTeamsPlayerSeason)`?
## Warning: Problem with `mutate()` input `Rk`.
## ℹ NAs introduced by coercion
## ℹ Input `Rk` is `Rk %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `Age`.
## ℹ NAs introduced by coercion
## ℹ Input `Age` is `Age %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `G`.
## ℹ NAs introduced by coercion
## ℹ Input `G` is `G %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `GS`.
## ℹ NAs introduced by coercion
## ℹ Input `GS` is `GS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `MP`.
## ℹ NAs introduced by coercion
## ℹ Input `MP` is `MP %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FG`.
## ℹ NAs introduced by coercion
## ℹ Input `FG` is `FG %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FGA`.
## ℹ NAs introduced by coercion
## ℹ Input `FGA` is `FGA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FG.`.
## ℹ NAs introduced by coercion
## ℹ Input `FG.` is `FG. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3P`.
## ℹ NAs introduced by coercion
## ℹ Input `X3P` is `X3P %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3PA`.
## ℹ NAs introduced by coercion
## ℹ Input `X3PA` is `X3PA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X3P.`.
## ℹ NAs introduced by coercion
## ℹ Input `X3P.` is `X3P. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X2P`.
## ℹ NAs introduced by coercion
## ℹ Input `X2P` is `X2P %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X2PA`.
## ℹ NAs introduced by coercion
## ℹ Input `X2PA` is `X2PA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `X2P.`.
## ℹ NAs introduced by coercion
## ℹ Input `X2P.` is `X2P. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `eFG.`.
## ℹ NAs introduced by coercion
## ℹ Input `eFG.` is `eFG. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FT`.
## ℹ NAs introduced by coercion
## ℹ Input `FT` is `FT %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FTA`.
## ℹ NAs introduced by coercion
## ℹ Input `FTA` is `FTA %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `FT.`.
## ℹ NAs introduced by coercion
## ℹ Input `FT.` is `FT. %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `ORB`.
## ℹ NAs introduced by coercion
## ℹ Input `ORB` is `ORB %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `DRB`.
## ℹ NAs introduced by coercion
## ℹ Input `DRB` is `DRB %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TRB`.
## ℹ NAs introduced by coercion
## ℹ Input `TRB` is `TRB %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `AST`.
## ℹ NAs introduced by coercion
## ℹ Input `AST` is `AST %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `STL`.
## ℹ NAs introduced by coercion
## ℹ Input `STL` is `STL %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `BLK`.
## ℹ NAs introduced by coercion
## ℹ Input `BLK` is `BLK %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `TOV`.
## ℹ NAs introduced by coercion
## ℹ Input `TOV` is `TOV %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `PF`.
## ℹ NAs introduced by coercion
## ℹ Input `PF` is `PF %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## Warning: Problem with `mutate()` input `PTS`.
## ℹ NAs introduced by coercion
## ℹ Input `PTS` is `PTS %>% as.numeric()`.
## Warning in function_list[[k]](value): NAs introduced by coercion
## parsed http://www.basketball-reference.com/leagues/NBA_2020_totals.html
## Warning: All elements of `...` must be named.
## Did you want `dataTable = c(isSeasonCurrent, slugPlayerSeason, slugPlayerBREF, namePlayer,
## slugPosition, agePlayer, slugTeamBREF, countGames, countGamesStarted,
## minutes, fgm, fga, pctFG, fg3m, fg3a, pctFG3, fg2m, fg2a,
## pctFG2, pctEFG, ftm, fta, pctFT, orb, drb, trb, ast, stl,
## blk, tov, pf, pts, isHOFPlayer, slugTeamsBREF, countTeamsPlayerSeason)`?
## Advanced
## Warning: `cols` is now required when using unnest().
## Please use `cols = c(dataTable)`
## Warning: The `x` argument of `as_tibble.matrix()` must have unique column names if `.name_repair` is omitted as of tibble 2.0.0.
## Using compatibility `.name_repair`.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
##
## Attaching package: 'purrr'
## The following object is masked from 'package:plyr':
##
## compact
## Totals
## Warning: `cols` is now required when using unnest().
## Please use `cols = c(dataTable)`
## Warning: Unknown columns: `typeData`
## Joining, by = c("slugSeason", "yearSeason", "isSeasonCurrent", "slugPlayerSeason", "slugPlayerBREF", "namePlayer", "slugPosition", "agePlayer", "slugTeamBREF", "countGames", "isHOFPlayer", "slugTeamsBREF", "idPlayerNBA", "urlPlayerThumbnail", "urlPlayerHeadshot", "urlPlayerPhoto", "urlPlayerStats", "urlPlayerActionPhoto")
## # A tibble: 529 x 67
## slugSeason namePlayer groupPosition yearSeason slugPosition isSeasonCurrent
## <chr> <chr> <chr> <dbl> <chr> <lgl>
## 1 2019-20 Steven Ad… C 2020 C FALSE
## 2 2019-20 Bam Adeba… F 2020 PF FALSE
## 3 2019-20 LaMarcus … C 2020 C FALSE
## 4 2019-20 Kyle Alex… F 2020 PF FALSE
## 5 2019-20 Nickeil A… G 2020 SG FALSE
## 6 2019-20 Grayson A… G 2020 SG FALSE
## 7 2019-20 Jarrett A… C 2020 C FALSE
## 8 2019-20 Kadeem Al… G 2020 SG FALSE
## 9 2019-20 Al-Farouq… F 2020 PF FALSE
## 10 2019-20 Justin An… F 2020 SF FALSE
## # … with 519 more rows, and 61 more variables: slugPlayerSeason <chr>,
## # slugPlayerBREF <chr>, agePlayer <dbl>, slugTeamBREF <chr>,
## # countGames <dbl>, isHOFPlayer <lgl>, slugTeamsBREF <chr>,
## # idPlayerNBA <dbl>, urlPlayerThumbnail <chr>, urlPlayerHeadshot <chr>,
## # urlPlayerPhoto <chr>, urlPlayerStats <chr>, urlPlayerActionPhoto <chr>,
## # minutes <dbl>, ratioPER <dbl>, pctTrueShooting <dbl>, pct3PRate <dbl>,
## # pctFTRate <dbl>, pctORB <dbl>, pctDRB <dbl>, pctTRB <dbl>, pctAST <dbl>,
## # pctSTL <dbl>, pctBLK <dbl>, pctTOV <dbl>, pctUSG <dbl>, ratioOWS <dbl>,
## # ratioDWS <dbl>, ratioWS <dbl>, ratioWSPer48 <dbl>, ratioOBPM <dbl>,
## # ratioDBPM <dbl>, ratioBPM <dbl>, ratioVORP <dbl>,
## # countTeamsPlayerSeason <dbl>, countGamesStarted <dbl>, pctFG <dbl>,
## # pctFG3 <dbl>, pctFG2 <dbl>, pctEFG <dbl>, pctFT <dbl>, minutesTotals <dbl>,
## # fgmTotals <dbl>, fgaTotals <dbl>, fg3mTotals <dbl>, fg3aTotals <dbl>,
## # fg2mTotals <dbl>, fg2aTotals <dbl>, ftmTotals <dbl>, ftaTotals <dbl>,
## # orbTotals <dbl>, drbTotals <dbl>, trbTotals <dbl>, astTotals <dbl>,
## # stlTotals <dbl>, blkTotals <dbl>, tovTotals <dbl>, pfTotals <dbl>,
## # ptsTotals <dbl>, countTeamsPlayerSeasonTotals <dbl>, urlPlayerBREF <chr>
bref_advanced <- dataBREFPlayerAdvanced
bref_totals <- dataBREFPlayerTotals
# Filter down to more than 500 total minutes and url shenanigans
adv_player_stats <- bref_advanced %>%
filter(minutes >= 500) %>%
mutate(bref_url = glue::glue("https://www.basketball-reference.com/players/{stringr::str_sub(idPlayerNBA, 1, 1)}/{idPlayerNBA}.html"),
bref_link = glue::glue('<a href="{bref_url}">{namePlayer}</a>'))
# Collapse into frontcourt and backcourt
unique_positions <- unique(bref_advanced$slugPosition)
frontcourt <- c("PF", "SF", "C", "PF-SF", "C-PF", "SG-PF", "SF-PF")
backcourt <- c("PG", "SG", "PG-SG", "SG-PG", "SF-SG", "SG-SF")
bref_efg <- bref_totals %>%
select(one_of(c("idPlayerNBA", "pctEFG")))
adv_player_stats <- adv_player_stats %>%
left_join(bref_efg, by = "idPlayerNBA") %>%
mutate( "position" = case_when(
slugPosition %in% frontcourt ~ "frontcourt",
slugPosition %in% backcourt ~ "backcourt",
TRUE ~ "other"),
"position" = as.factor(position)
)
# Uses NBA Stats API to get offensive and defensive rating
nbastatR::teams_players_stats(seasons = 2020, types = c("player"), tables = "general", measures = "Advanced", assign_to_environment = TRUE)
## Acquiring all player PerGame general Advanced split tables for the 2019-20 season
## Warning: Unknown columns: `orderSort`, `idLeague`, `namePlayerLastFirst`,
## `dateGameLastPlayed`
## Warning: Unknown columns: `idTeam`
## Joining, by = "numberTable"
## Warning: All elements of `...` must be named.
## Did you want `dataTable = c(typeMeasure, isPlusMinus, isPaceAdjust, isRank, idPlayoffRound,
## idMonth, idTeamOpponent, idPeriod, countLastNGames, namePlayer,
## slugTeam, idPlayer, idTeam, gp, pctWins, pctAST, pctOREB,
## pctDREB, pctTREB, pctTOVTeam, pctTOVE, pctEFG, pctTS, pctUSG,
## pctUSGE, fgm, fga, fgmPerGame, fgaPerGame, pctFG, gpRank,
## pctWinsRank, minutesRank, pctASTRank, pctOREBRank, pctDREBRank,
## pctTREBRank, pctTOVTmRank, pctEFGRank, pctTSRank, pctUSGRank,
## fgmRank, fgaRank, fgmPerGameRank, fgaPerGameRank, pctFGRank,
## agePlayer, wins, losses, minutes, ortgE, ortg, removeOFF_RATING,
## drtgE, drtg, removeDEF_RATING, netrtgE, netrtg, removeNET_RATING,
## ratioASTtoTO, ratioAST, paceE, pace, pacePer40PACE_PER40,
## removePACE, ratioPIE, possessions, winsRank, lossesRank,
## rankORTGE, ortgRank, removeOFF_RATING_RANK, rankDRTGE, drtgRank,
## removeDEF_RATING_RANK, rankNTRGE, netrtgRank, removeNET_RATING_RANK,
## ratioASTtoTORank, ratioASTRank, rankPCTOVE, rankPCTUSGE,
## rankPACEE, paceRank, removePACE_RANK, pieRank)`?
## Warning: `cols` is now required when using unnest().
## Please use `cols = c(dataTable)`
## # A tibble: 1 x 7
## nameTable typeResult modeSearch slugSeason typeSeason yearSeason dataTable
## <chr> <chr> <chr> <chr> <chr> <dbl> <list>
## 1 general player PerGame 2019-20 Regular Sea… 2020 <tibble [5…
player_rtgs <- dataGeneralPlayers %>%
select(one_of(c("idPlayer", "ortg", "drtg")))
adv_player_stats <- adv_player_stats %>%
left_join(player_rtgs, by = c("idPlayerNBA" = "idPlayer"))
# Graph of PER for players with 500 plus minutes
adv_player_stats %>%
ggplot(aes(x = ratioPER)) +
geom_histogram(alpha = 0.7, fill = "#011627") +
labs(title = "PER for players with 500+ minutes",
subtitle = "NBA 2019-2020 season",
caption = glue::glue("data via nbastatR")) + theme_bw()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Graph of VORP
adv_player_stats %>%
ggplot(aes(x = ratioVORP)) +
geom_histogram(alpha = 0.7, fill = "#011627") +
labs(title = "Value Over Replacement Player (VORP)",
subtitle = "NBA 2019-2020 season, players with 500+ minutes",
caption = glue::glue("data via nbastatR")) + theme_bw()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Graph of win shares
adv_player_stats %>%
ggplot(aes(x = ratioWS)) +
geom_histogram(alpha = 0.7, fill = "#011627") +
labs(title = "Win Shares for players with 500+ minutes",
subtitle = "NBA 2019-2020 season",
caption = glue::glue("data via nbastatR")) + theme_bw()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
adv_player_stats %>%
ggplot(aes(x = ratioOBPM, y = ratioDBPM)) +
geom_point() +
geom_hline(yintercept = 0, alpha = 0.6, lty = "dashed") +
geom_vline(xintercept = 0, alpha = 0.6, lty = "dashed") +
labs(title = "Offensive vs. Defensive Box Plus-Minus",
subtitle = glue::glue("NBA 2019-2020 season"),
caption = glue::glue("data via nbastatR"),
x = "OBPM",
y = "DBPM") + theme_bw()
# Get top 10 players for some variable
get_top10 <- function(df, column) {
require(rlang)
column <- enquo(column)
dplyr::top_n(df, n = 10, wt = !!column) %>%
pull(namePlayer)
}
# get top 10 for desired variable (in this case ratioBPM)
top10_BPM <- top_n(adv_player_stats, n = 10, wt = ratioBPM) %>%
pull(namePlayer)
# adv_player_stats %>%
# ggplot(aes(x = ratioOBPM, y = ratioDBPM)) +
# geom_point(color = "#011627") +
# gghighlight::gghighlight(namePlayer %in% top10_BPM, label_key = namePlayer,
# label_params = list(fill = ggplot2::alpha("white", 0.8),
# box.padding = 0,
# family = "Roboto Condensed"),
# unhighlighted_colour = "#007190") +
# geom_hline(yintercept = 0, alpha = 0.6, lty = "dashed") +
# geom_vline(xintercept = 0, alpha = 0.6, lty = "dashed") +
# labs(title = "Offensive vs. Defensive Box Plus-Minus: Top 10 Box Plus/Minus",
# subtitle = glue::glue("NBA 2019-2020 Season"),
# caption = glue::glue("data via nbastatR"),
# x = "OBPM",
# y = "DBPM")
adv_player_stats %>%
select(namePlayer, slugPosition, ratioBPM, ratioOBPM, ratioDBPM, bref_url, urlPlayerHeadshot) %>%
arrange(desc(ratioBPM)) %>%
top_n(n = 10, wt = ratioBPM) %>%
gt::gt(rowname_col = "namePlayer") %>%
tab_header(
title = md("**Top 10 Box Plus/Minus**")
) %>%
cols_label(
slugPosition = md("**Position**"),
ratioBPM = md("**BPM**"),
ratioOBPM = md("**OBPM**"),
ratioDBPM = md("**DBPM**"),
bref_url = md("**Link**"),
urlPlayerHeadshot = md("")
) %>%
text_transform(
locations = cells_data(vars(bref_url)),
fn = function(x) {
sprintf("<a href=%s>profile</a>", x)
}
) %>%
text_transform(
locations = cells_data(vars(urlPlayerHeadshot)),
fn = function(x) {
web_image(url = x)
}
) %>%
tab_source_note(
md("source: [basketball-reference.com](https://www.basketball-reference.com) via [nbastatR](http://asbcllc.com/nbastatR/index.html)")
) %>%
tab_footnote(
footnote = ("Players with 500+ minutes."),
locations = cells_title("title")
) %>%
tab_footnote(
footnote = ("Box Plus/Minus: a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team."),
locations = cells_column_labels(
columns = vars(ratioBPM)
)
) %>%
tab_footnote(
footnote = ("Offensive Box Plus/Minus."),
locations = cells_column_labels(
columns = vars(ratioOBPM)
)
) %>%
tab_footnote(
footnote = ("Defensive Box Plus/Minus."),
locations = cells_column_labels(
columns = vars(ratioDBPM)
)
) %>%
tab_options(table.width = px(640))
## Warning: The `cells_data()` function is deprecated and will soon be removed
## * Use the `cells_body()` function instead
## Warning: The `cells_data()` function is deprecated and will soon be removed
## * Use the `cells_body()` function instead
| Top 10 Box Plus/Minus1 | ||||||
|---|---|---|---|---|---|---|
| Position | BPM2 | OBPM3 | DBPM4 | Link | ||
| Giannis Antetokounmpo | PF | 11.5 | 7.4 | 4.1 | profile | ![]() |
| James Harden | SG | 9.6 | 8.1 | 1.6 | profile | ![]() |
| Kawhi Leonard | SF | 8.9 | 6.5 | 2.4 | profile | ![]() |
| Luka Doncic | PG | 8.4 | 7.4 | 1.0 | profile | ![]() |
| LeBron James | PG | 8.4 | 6.6 | 1.8 | profile | ![]() |
| Anthony Davis | PF | 8.0 | 5.4 | 2.6 | profile | ![]() |
| Karl-Anthony Towns | C | 7.8 | 7.0 | 0.8 | profile | ![]() |
| Kyrie Irving | PG | 7.7 | 6.7 | 0.9 | profile | ![]() |
| Damian Lillard | PG | 7.5 | 8.3 | -0.9 | profile | ![]() |
| Nikola Jokic | C | 7.4 | 5.5 | 2.0 | profile | ![]() |
| source: basketball-reference.com via nbastatR | ||||||
|
1
Players with 500+ minutes.
2
Box Plus/Minus: a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.
3
Offensive Box Plus/Minus.
4
Defensive Box Plus/Minus.
|
||||||
adv_player_stats %>%
select(urlPlayerHeadshot, namePlayer, slugPosition, ratioBPM, ratioOBPM, ratioDBPM) %>%
arrange(desc(ratioOBPM)) %>%
top_n(n = 10, wt = ratioOBPM) %>%
gt::gt() %>%
tab_header(
title = md("**Top 10 Offensive Box Plus/Minus**")
) %>%
cols_label(
namePlayer = md("**Player**"),
urlPlayerHeadshot = md(""),
slugPosition = md("**Position**"),
ratioBPM = md("**BPM**"),
ratioOBPM = md("**OBPM**"),
ratioDBPM = md("**DBPM**")
) %>%
text_transform(
locations = cells_data(vars(urlPlayerHeadshot)),
fn = function(x) {
web_image(url = x)
}
) %>%
tab_source_note(
md("source: [basketball-reference.com](https://www.basketball-reference.com) via [nbastatR](http://asbcllc.com/nbastatR/index.html)")
) %>%
tab_footnote(
footnote = ("Players with 500+ minutes."),
locations = cells_title("title")
) %>%
tab_footnote(
footnote = ("Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team."),
locations = cells_column_labels(
columns = vars(ratioBPM)
)
) %>%
tab_footnote(
footnote = ("Offensive Box Plus/Minus."),
locations = cells_column_labels(
columns = vars(ratioOBPM)
)
) %>%
tab_footnote(
footnote = ("Defensive Box Plus/Minus."),
locations = cells_column_labels(
columns = vars(ratioDBPM)
)
) %>%
tab_options(table.width = px(640))
## Warning: The `cells_data()` function is deprecated and will soon be removed
## * Use the `cells_body()` function instead
| Top 10 Offensive Box Plus/Minus1 | |||||
|---|---|---|---|---|---|
| Player | Position | BPM2 | OBPM3 | DBPM4 | |
![]() |
Damian Lillard | PG | 7.5 | 8.3 | -0.9 |
![]() |
James Harden | SG | 9.6 | 8.1 | 1.6 |
![]() |
Giannis Antetokounmpo | PF | 11.5 | 7.4 | 4.1 |
![]() |
Luka Doncic | PG | 8.4 | 7.4 | 1.0 |
![]() |
Karl-Anthony Towns | C | 7.8 | 7.0 | 0.8 |
![]() |
Kyrie Irving | PG | 7.7 | 6.7 | 0.9 |
![]() |
LeBron James | PG | 8.4 | 6.6 | 1.8 |
![]() |
Kawhi Leonard | SF | 8.9 | 6.5 | 2.4 |
![]() |
Trae Young | PG | 3.9 | 6.2 | -2.3 |
![]() |
Nikola Jokic | C | 7.4 | 5.5 | 2.0 |
| source: basketball-reference.com via nbastatR | |||||
|
1
Players with 500+ minutes.
2
Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.
3
Offensive Box Plus/Minus.
4
Defensive Box Plus/Minus.
|
|||||
adv_player_stats %>%
select(urlPlayerHeadshot, namePlayer, slugPosition, ratioBPM, ratioOBPM, ratioDBPM) %>%
arrange(desc(ratioDBPM)) %>%
top_n(n = 10, wt = ratioDBPM) %>%
gt::gt() %>%
tab_header(
title = md("**Top 10 Defensive Box Plus/Minus**")
) %>%
cols_label(
namePlayer = md("**Player**"),
urlPlayerHeadshot = md(""),
slugPosition = md("**Position**"),
ratioBPM = md("**BPM**"),
ratioOBPM = md("**OBPM**"),
ratioDBPM = md("**DBPM**")
) %>%
text_transform(
locations = cells_data(vars(urlPlayerHeadshot)),
fn = function(x) {
web_image(url = x)
}
) %>%
tab_source_note(
md("source: [basketball-reference.com](https://www.basketball-reference.com) via [nbastatR](http://asbcllc.com/nbastatR/index.html)")
) %>%
tab_footnote(
footnote = ("Players with 500+ minutes."),
locations = cells_title("title")
) %>%
tab_footnote(
footnote = ("Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team."),
locations = cells_column_labels(
columns = vars(ratioBPM)
)
) %>%
tab_footnote(
footnote = ("Offensive Box Plus/Minus."),
locations = cells_column_labels(
columns = vars(ratioOBPM)
)
) %>%
tab_footnote(
footnote = ("Defensive Box Plus/Minus."),
locations = cells_column_labels(
columns = vars(ratioDBPM)
)
) %>%
tab_options(table.width = px(640))
## Warning: The `cells_data()` function is deprecated and will soon be removed
## * Use the `cells_body()` function instead
| Top 10 Defensive Box Plus/Minus1 | |||||
|---|---|---|---|---|---|
| Player | Position | BPM2 | OBPM3 | DBPM4 | |
![]() |
Giannis Antetokounmpo | PF | 11.5 | 7.4 | 4.1 |
![]() |
Nerlens Noel | C | 3.1 | -0.3 | 3.4 |
![]() |
Kris Dunn | PG | -0.6 | -3.7 | 3.1 |
![]() |
Matisse Thybulle | SG | 0.3 | -2.8 | 3.1 |
![]() |
Jonathan Isaac | SF | 2.3 | -0.5 | 2.9 |
![]() |
Marc Gasol | C | 1.6 | -1.2 | 2.8 |
![]() |
Anthony Davis | PF | 8.0 | 5.4 | 2.6 |
![]() |
Patrick Beverley | PG | 2.2 | -0.3 | 2.5 |
![]() |
Brook Lopez | C | 2.0 | -0.4 | 2.5 |
![]() |
Alex Caruso | PG | -0.2 | -2.6 | 2.4 |
![]() |
Donte DiVincenzo | SG | 1.3 | -1.1 | 2.4 |
![]() |
Kawhi Leonard | SF | 8.9 | 6.5 | 2.4 |
| source: basketball-reference.com via nbastatR | |||||
|
1
Players with 500+ minutes.
2
Box Plus/Minus; a box score estimate of the points per 100 possessions that a player contributed above a league-average player, translated to an average team.
3
Offensive Box Plus/Minus.
4
Defensive Box Plus/Minus.
|
|||||
library(highcharter)
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
#> Highcharts (www.highcharts.com) is a Highsoft software product which is
#> not free for commercial and Governmental use
hchart(adv_player_stats, "scatter", hcaes(x = "ratioOBPM", y = "ratioDBPM", group = "position", name = "namePlayer", OBPM = "ratioOBPM", DBPM = "ratioDBPM", position = "position")) %>%
hc_tooltip(pointFormat = "<b>{point.name}</b><br />OBPM: {point.OBPM}<br />DBPM: {point.DBPM}") %>%
hc_title(text = "Offensive vs. Defensive Box Plus/Minus") %>%
hc_subtitle(text = "NBA 2019-2020 Season") %>%
hc_credits(enabled = TRUE,
text = "data via nbastatR",
style = list(
fontSize = "10px"
)
) %>%
hc_add_theme(hc_theme_538())
hchart(adv_player_stats, "scatter", hcaes(x = "ratioOWS", y = "ratioDWS", group = "position", name = "namePlayer", OWS = "ratioOWS", DWS = "ratioDWS", position = "position")) %>%
hc_tooltip(pointFormat = "<b>{point.name}</b><br />OWS: {point.OWS}<br />DWS: {point.DWS}") %>%
hc_title(text = "Offensive vs. Defensive Win Shares") %>%
hc_subtitle(text = "NBA 2019-2020 Season") %>%
hc_credits(enabled = TRUE,
text = "data via nbastatR",
style = list(
fontSize = "10px"
)
) %>%
hc_add_theme(hc_theme_economist())
hchart(adv_player_stats, "scatter",
hcaes(x = "pctTrueShooting", y = "ratioPER",
name = "namePlayer", TS = "pctTrueShooting",
PER = "ratioPER", position = "position")) %>%
hc_tooltip(pointFormat = "<b>{point.name}</b><br />TS%: {point.TS}<br />PER: {point.PER}<br />Position: {point.position}") %>%
hc_title(text = "True Shooting % vs Player Efficiency Rating") %>%
hc_subtitle(text = "NBA 2019-2020 Season") %>%
hc_credits(enabled = TRUE,
text = "data via nbastatR",
style = list(
fontSize = "14px"
)
) %>%
hc_add_theme(hc_theme_chalk(
plotOptions = list(
scatter = list(
marker = list(radius = 4,
fillOpacity = 0.3) # actually this does nothing
)
)
)
)
hc <- hchart(adv_player_stats, "scatter", hcaes(x = "ratioOWS", y = "ratioDWS", group = "position", name = "namePlayer", OWS = "ratioOWS", DWS = "ratioDWS", Position = "position")) %>%
hc_tooltip(pointFormat = "<b>{point.name}</b><br />OWS: {point.OWS}<br />DWS: {point.DWS}") %>%
hc_title(text = "Offensive vs. Defensive Win Shares") %>%
hc_subtitle(text = "NBA 2019-2020 Season") %>%
hc_credits(enabled = TRUE,
text = "by @dataandme data via nbastatR",
href = "https://github.com/abresler/nbastatR",
style = list(
fontSize = "10px",
color = "#4a4a4a"
)
)
hc2 <- hchart(adv_player_stats, "scatter",
hcaes(x = "ortg", y = "drtg", group = "position",
name = "namePlayer", ortg = "ortg",
drtg = "drtg", position = "position")) %>%
hc_tooltip(pointFormat = "<b>{point.name}</b><br />ORTG: {point.ortg}<br />DRTG: {point.drtg}<br />Position: {point.position}") %>%
hc_title(text = "Offensive vs. Defensive Rating") %>%
hc_subtitle(text = "NBA 2019-2020 Season") %>%
hc_credits(enabled = TRUE,
text = "data via nbastatR",
style = list(
fontSize = "14px"
)
)
hc
hc2